#ifndef QXGAME_GAMEINFO_H
#define QXGAME_GAMEINFO_H

#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
#include "json.hpp"
#include "SDL.h"
#include "SDL_ttf.h"
#include "SDL_image.h"
#include "SDL_mixer.h"
#include "Singleton.h"
#include "TexId.h"
#include "MixId.h"
#include "MusicId.h"
#include "GameMusic.h"
#include "../map/Map.h"
#include "../ui/StatusBar.h"
#include "../wave/Wave.h"
#include "../object/base/Object.h"
#include "../object/base/Character.h"
#include "../object/skill/Skill.h"
#include "SkillId.h"
#include "CharacterId.h"

#define GAME_INFO (GameInfo::Instance())
#define GAME_RENDERER (GameInfo::Instance().renderer)
#define GAME_EVENT (GameInfo::Instance().event)
#define GAME_PAUSE_MARK (GameInfo::Instance().isPause)
#define GAME_MUSIC (GameInfo::Instance().music)

using json = nlohmann::json;

class GameInfo : public Singleton<GameInfo> {
    friend class Singleton<GameInfo>;

public:
    struct HeroInfo {
        int characterId, speed, maxSpeed, hp, maxHp, mp, maxMp, recoverMp, recoverHp, width
        , height, attackWidth, attackHeight, damage;
    };

    bool LoadFromFile();
    void InMap(GameVector &position) const;
    static bool CheckCollision(Object *object);
    static void CalSkillPosition(GameVector &position, double &angle, std::shared_ptr<SkillId> skill);

private:
    bool ParseStaticFile();
    bool ParseTex(const json &root);
    bool ParseMix(const json &root);
    bool ParseMusic(const json &root);
    bool ParseCharacter();
    bool ParseHero(const json &root);

public:
    TTF_Font *font;
    std::unordered_map<MixId, Mix_Chunk *> mixPool;
    std::unordered_map<MusicId, Mix_Music *> musicPool;
    std::unordered_map<TexId, SDL_Texture *> texturePool;
    std::unordered_map<CharacterId, HeroInfo> heroInfoPool;

    std::atomic<int> coins = 0;
    std::atomic<double> gameTime = 0;
    std::atomic<bool> isGameOver = false;
    Map map;
    SDL_Event event;
    SDL_Renderer *renderer = nullptr;
    StatusBar statusBar;

    int windowWidth = 1280;
    int windowHeight = 720;
    int gameWindowWidth = 1280;
    int gameWindowHeight = 620;
    std::atomic<bool> isPause = true;


    GameMusic music;
    std::vector<std::shared_ptr<Character>> players;
    std::vector<std::shared_ptr<Character>> enemies;
    std::vector<std::shared_ptr<Skill>> skills;
    std::vector<std::shared_ptr<Wave>> waves;
    static std::unordered_map<SkillId, int> skillConsume;
};


#endif // QXGAME_GAMEINFO_H
